home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / dnet / mailchk.lha / Mailchk / unix / server / smailchk.c < prev   
Encoding:
C/C++ Source or Header  |  1990-03-05  |  7.5 KB  |  314 lines

  1.  
  2. /*
  3.  *    SMAILCHK.C
  4.  *
  5.  *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *      Check the mailbox and reports if new mail
  8.  *      has arrived.  Connects to the Mailchk client on the Amiga.
  9.  *      Accepts only one connection.
  10.  *      
  11.  *      Written by S. Laroche.  
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <sys/time.h>
  16. #include <sys/file.h>
  17. #include <errno.h>
  18. #include <signal.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21.  
  22. #include "servers.h"
  23.  
  24. #define BUFLENGTH 512
  25.  
  26. extern int errno;
  27.  
  28. void do_mailchk();
  29. char delmailmsg();
  30. char copyfiles();
  31.  
  32. long numsecs;
  33. char firstrun;
  34. int fd;
  35.  
  36. main(ac,av)
  37. char *av[];
  38. {
  39.     long chann = DListen(PORT_MAILCHK);
  40.     char result;
  41.  
  42.     if (av[1])
  43.     chdir(av[1]);
  44.     signal(SIGPIPE, SIG_IGN);
  45.     signal(SIGALRM, do_mailchk);
  46.     for (;;) {
  47.     fd = DAccept(chann);
  48.     if (fd < 0) {
  49.         if (errno == EINTR)
  50.         continue;
  51.         break;
  52.     }
  53.         getmailpath();
  54.         while (ggread(fd,&result,1) == 1) {
  55.           Whatdoyouwant(fd,result);
  56.         }
  57.         close(fd);
  58.         _exit(1);
  59.     }
  60.     perror("SMAILCHK");
  61. }
  62.  
  63. char buf[256], mname[256];
  64.  
  65. getmailpath()
  66.  
  67. {
  68.     char *buffer;
  69.  
  70.     buffer = (char *) getenv("MAIL");
  71.     if (buffer == NULL) {
  72.        strcpy(mname,"/var/spool/mail/");
  73.     }
  74.     else {
  75.        strcpy(mname,buffer);
  76.        strcat(mname,"/");
  77.     }
  78.     cuserid(buf);
  79.     strcat(mname,buf);
  80. }
  81.  
  82. Whatdoyouwant(fd,result)
  83.  
  84. int fd;
  85. char result;
  86.  
  87. /*  This function interprets requests from the Amiga client.
  88.     0 -> Do nothing
  89.     1 -> Send the mail header from Mail.
  90.     2 -> Send a particular message.
  91.     3 -> Delete a particular message.
  92.     4 -> Initial handshake
  93. */
  94.  
  95. {
  96.     char dummy, *buffer;
  97.     FILE *fi;
  98.  
  99.     switch(result) {
  100.         case 1 : 
  101.           fi = popen("mail -H","r");
  102.           if (fi == NULL) {
  103.               perror("SMAILCHK, mail program not found");
  104.               exit(0);
  105.           }
  106.           while (fgets(buf,256,fi) != NULL) {
  107.             dummy = strlen(buf);
  108.             buf[dummy-1] = 0;
  109.             gwrite(fd,&dummy,1);
  110.             gwrite(fd,buf,dummy);
  111.           }
  112.           dummy = 0;
  113.           gwrite(fd,&dummy,1);
  114.       if (ferror(fi)) {
  115.             perror("SMAILCHK, error executing mail");
  116.         exit(0);
  117.           }
  118.       pclose(fi);
  119.           break;
  120.         case 2 :
  121.           buffer = (char *) malloc(BUFLENGTH);
  122.           if (buffer == NULL) {
  123.               fprintf(stderr,"SMAILCHK:  not enough memory\n");
  124.           }
  125.           else {
  126.               sendmailmsg(fd,mname,buffer);
  127.               free(buffer);
  128.           }
  129.           break;
  130.     case 3 :
  131.           { char ok;
  132.            
  133.           ok = delmailmsg(fd,mname);
  134.           gwrite(fd,&ok,1);
  135.            if (ok) { alarm(0); do_mailchk();}
  136.           }
  137.           break;
  138.         case 4 :
  139.           if ((ggread(fd,&numsecs,4)  == 4) &&
  140.               (ggread(fd,&firstrun,1) == 1)) { alarm(0); do_mailchk(); }
  141.           else { close(fd); _exit(1); }
  142.     }
  143. }
  144.  
  145. void do_mailchk()
  146.  
  147. {
  148.     char dummy, *s_mtime;
  149.     struct stat tempbuf;
  150.     static char nomail = 1;
  151.     static long lasttime = 0;
  152.     
  153.     strcpy(buf,"=");
  154.     alarm(numsecs);
  155.     if (stat(mname,&tempbuf) == -1) {
  156.         if (errno == ENOENT) { if (nomail) {
  157.                                    strcpy(buf,"No mail.");
  158.                                    nomail = 0;
  159.                                }
  160.         }
  161.         else perror("SMAILCHK, Unable to examine file");
  162.     }
  163.     else {
  164.         if (tempbuf.st_mtime >= tempbuf.st_atime) {
  165.             s_mtime = ctime(&tempbuf.st_mtime); 
  166.             strcpy(buf,"New mail arrived on "); 
  167.             strcat(buf,s_mtime);
  168.             nomail = 1;
  169.         }
  170.         else if ((firstrun && (tempbuf.st_mtime > lasttime)) ||
  171.                   firstrun == 2)
  172.                  strcpy(buf,"You have mail\n");
  173.         lasttime = tempbuf.st_mtime;
  174.     }
  175.     dummy = strlen(buf);
  176.     if (dummy > 2) {
  177.         gwrite(fd, &dummy, 1);
  178.         gwrite(fd, buf, dummy);
  179.     }
  180.     firstrun = 1;
  181. }
  182.  
  183. sendmailmsg(fd,mname,buffer)
  184.  
  185. char *buffer, *mname;
  186. int fd;
  187.  
  188. {
  189.   int len= BUFLENGTH;
  190.   long nochars, stchar;
  191.   char dummy;
  192.   FILE *fi;
  193.  
  194.   if (ggread(fd,&stchar,4) == 4) {
  195.       if (ggread(fd,&nochars,4) == 4) {
  196.           if (fi = fopen(mname,"r")) {
  197.               if (fseek(fi,stchar,0) < 0) {
  198.                   fclose(fi);
  199.                   exit;
  200.               }
  201.               else {
  202.                   dummy = 0;
  203.                   while (nochars > len) {
  204.                          fread(buffer,1,len,fi);
  205.                          nochars -= len;
  206.                          gwrite(fd,&len,4); 
  207.                          gwrite(fd,buffer,len);
  208.                          ggread(fd,&dummy,1);
  209.                          if (dummy) break;
  210.                         }
  211.                   if (dummy == 0) {
  212.                       if (fread(buffer,1,nochars,fi) != nochars) {
  213.                           perror("SMAILCHK, unable to read mail file");
  214.                           exit;
  215.                       }
  216.                       gwrite(fd,&nochars,4); 
  217.                       gwrite(fd,buffer,nochars);
  218.                       ggread(fd,&dummy,1);
  219.                       nochars = 0;
  220.                       gwrite(fd,&nochars,4);
  221.                   }
  222.               }
  223.               fclose(fi); 
  224.            }
  225.        }
  226.    }
  227. }
  228.  
  229. char delmailmsg(fd,mname)
  230.  
  231. char *mname;
  232. int fd;
  233.  
  234. {
  235.   long nochars, stchar;
  236.   FILE *f1, *f2;
  237.   char ok = 0, *tname;
  238.  
  239.  
  240.   if (!(tname = (char *) getenv("DNETDIR"))) return(ok);
  241.   strcpy(buf,tname);
  242.   strcat(buf,"MAIL0001");
  243.   if (ggread(fd,&stchar,4) == 4) 
  244.       if (ggread(fd,&nochars,4) == 4) 
  245.           if ((f1 = fopen(mname,"r")) && (f2 = fopen(buf,"w+"))) {
  246.               if (copyfiles(f1,f2,stchar)) 
  247.                   if (fseek(f1,nochars,1) == 0) 
  248.                       if (ok = copyfiles(f1,f2,-1)) {
  249.                           fclose(f1);
  250.                           if (unlink(mname) < 0) {
  251.                               perror("SMAILCHK, Error while removing");
  252.                               fclose(f2);
  253.                               unlink(buf);
  254.                               return(0);
  255.                           }
  256.                           rewind(f2);
  257.                           if (f1 = fopen(mname,"w")) {
  258.                               fchmod(f1,0600);
  259.                               ok = copyfiles(f2,f1,-1);
  260.                               fclose(f1);
  261.                               fclose(f2);
  262.                               unlink(buf);
  263.                           }
  264.                           else {
  265.                               perror("SMAILCHK, Error writing in spool dir");
  266.                               fclose(f2);
  267.                               return(0);
  268.                           }
  269.                           if (f1 = fopen(mname,"r")) { /* Touch the file */
  270.                               char f = 0;
  271.                               fseek(f1,0,2);
  272.                               if (ftell(f1) < 2) f = 1; 
  273.                               fclose(f1);
  274.                               if (f) unlink(mname);
  275.                           }
  276.                           return(ok);
  277.                       }
  278.               perror("SMAILCHK, Error while writing");
  279.               fclose(f1);
  280.               fclose(f2);
  281.               return(0);
  282.           }
  283.   perror("SMAILCHK, Delete operation");
  284.   return(0);
  285. }
  286.  
  287. char copyfiles(f1,f2,n)
  288.  
  289. FILE *f1, *f2;
  290. long n;
  291.  
  292. {
  293.   char buffer[1024], ok = 1;
  294.   int tmp;
  295.  
  296.   while (n > 1024 || n < 0) {
  297.     if (n > 0) n -= 1024;
  298.     if ((tmp = fread(buffer,1,1024,f1)) == 1024) 
  299.         if (fwrite(buffer,1,1024,f2) == 1024)
  300.             continue;
  301.     ok = 0;
  302.     break;
  303.   }
  304.   while (ok && n > 0) {
  305.       if (fread(buffer,1,n,f1) == n) 
  306.           if (fwrite(buffer,1,n,f2) == n)
  307.               break;
  308.       ok = 0;
  309.   }
  310.   if (n >= 0) return(ok); 
  311.   if (fwrite(buffer,1,tmp,f2) == tmp) ok = 1;
  312.   return(ok);
  313. }
  314.